/**
 * 腾讯云COS上传工具（后端上传方式）
 * 提供完整的前端文件上传功能，支持单文件、批量上传、进度跟踪等
 */
import request from '../utls/require'

/**
 * 上传结果接口
 */
export interface UploadResult {
  success: boolean
  url: string
  path: string
  message: string
  file?: File
  fileName?: string
  fileSize?: number
}

/**
 * 批量上传结果
 */
export interface BatchUploadResult {
  total: number
  success: number
  failed: number
  results: UploadResult[]
}

/**
 * 上传进度回调函数
 */
export interface UploadProgressCallback {
  (progress: number, loaded: number, total: number): void
}

/**
 * 上传配置选项
 */
export interface UploadOptions {
  folder?: string
  fileName?: string
  onProgress?: UploadProgressCallback
  maxSize?: number // 最大文件大小（字节）
  allowedTypes?: readonly string[] // 允许的文件类型
}

/**
 * 文件类型检查工具
 */
class FileValidator {
  /**
   * 检查文件大小是否超过限制
   */
  static checkFileSize(file: File, maxSize?: number): { valid: boolean; message: string } {
    if (!maxSize) return { valid: true, message: '' }
    
    if (file.size > maxSize) {
      const maxSizeMB = (maxSize / (1024 * 1024)).toFixed(2)
      const fileSizeMB = (file.size / (1024 * 1024)).toFixed(2)
      return {
        valid: false,
        message: `文件大小超过限制：${fileSizeMB}MB > ${maxSizeMB}MB`
      }
    }
    
    return { valid: true, message: '' }
  }

  /**
   * 检查文件类型是否允许
   */
  static checkFileType(file: File, allowedTypes?: readonly string[]): { valid: boolean; message: string } {
    if (!allowedTypes || allowedTypes.length === 0) return { valid: true, message: '' }
    
    const fileType = file.type.toLowerCase()
    const isAllowed = allowedTypes.some(type => 
      fileType.includes(type.toLowerCase()) || 
      file.name.toLowerCase().endsWith(type.toLowerCase())
    )
    
    if (!isAllowed) {
      return {
        valid: false,
        message: `文件类型不支持，支持的类型：${allowedTypes.join(', ')}`
      }
    }
    
    return { valid: true, message: '' }
  }
}

/**
 * 单文件上传到COS
 * 
 * @param file 文件对象
 * @param options 上传配置选项
 * @returns 上传结果
 */
export async function uploadToServer(
  file: File, 
  options: UploadOptions = {}
): Promise<UploadResult> {
  try {
    // 参数验证
    if (!file) {
      return {
        success: false,
        url: '',
        path: '',
        message: '文件不能为空'
      }
    }

    // 文件大小验证
    const sizeCheck = FileValidator.checkFileSize(file, options.maxSize)
    if (!sizeCheck.valid) {
      return {
        success: false,
        url: '',
        path: '',
        message: sizeCheck.message
      }
    }

    // 文件类型验证
    const typeCheck = FileValidator.checkFileType(file, options.allowedTypes)
    if (!typeCheck.valid) {
      return {
        success: false,
        url: '',
        path: '',
        message: typeCheck.message
      }
    }

    const formData = new FormData()
    formData.append('file', file)
    formData.append('folder', options.folder || 'zongce')
    
    if (options.fileName) {
      formData.append('custom_name', options.fileName)
    }

    const config: any = {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    }

    // 添加进度监听
    if (options.onProgress) {
      config.onUploadProgress = (progressEvent: any) => {
        const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
        options.onProgress!(progress, progressEvent.loaded, progressEvent.total)
      }
    }
    
    const response = await request.post('/cos/upload/', formData, config)
    
    return {
      success: true,
      url: response.data.url,
      path: response.data.path,
      message: '上传成功',
      file: file,
      fileName: file.name,
      fileSize: file.size
    }
  } catch (error: any) {
    const errorMessage = error.response?.data?.message || 
                        error.message || 
                        '上传失败，请检查网络连接'
    
    return {
      success: false,
      url: '',
      path: '',
      message: errorMessage,
      file: file,
      fileName: file.name,
      fileSize: file.size
    }
  }
}

/**
 * 批量上传文件到COS
 * 
 * @param files 文件对象数组
 * @param options 上传配置选项
 * @returns 批量上传结果
 */
export async function batchUploadToServer(
  files: File[],
  options: UploadOptions = {}
): Promise<BatchUploadResult> {
  if (!files || files.length === 0) {
    return {
      total: 0,
      success: 0,
      failed: 0,
      results: []
    }
  }

  const uploadPromises = files.map(file => uploadToServer(file, options))
  const results = await Promise.all(uploadPromises)
  
    const successCount = results.filter(result => result.success).length
    const failedCount = results.filter(result => !result.success).length

    return {
      total: files.length,
      success: successCount,
      failed: failedCount,
      results: results
    }
}

/**
 * 常用文件类型预设
 */
export const FileTypePresets = {
  images: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/jpg'],
  documents: ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
  videos: ['video/mp4', 'video/quicktime', 'video/x-msvideo'],
  audio: ['audio/mpeg', 'audio/wav', 'audio/ogg']
} as const

/**
 * 创建预配置的上传函数
 */
export function createUploader(options: UploadOptions = {}) {
  return {
    upload: (file: File) => uploadToServer(file, options),
    batchUpload: (files: File[]) => batchUploadToServer(files, options)
  }
}

/**
 * 默认图片上传配置（头像上传专用）
 */
export const avatarUploader = createUploader({
  folder: 'avatar',
  maxSize: 5 * 1024 * 1024, // 5MB
  allowedTypes: FileTypePresets.images
})

/**
 * 默认文档上传配置
 */
export const documentUploader = createUploader({
  folder: 'documents',
  maxSize: 10 * 1024 * 1024, // 10MB
  allowedTypes: FileTypePresets.documents
})